package com.traveldream.testing;

import java.util.Collections;
import java.util.Comparator;
import java.util.GregorianCalendar;
import java.util.List;

import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;

import com.traveldream.entities.Booking;
import com.traveldream.entities.BookingPK;
import com.traveldream.entities.DefaultPacket;
import com.traveldream.entities.Packet;
import com.traveldream.entities.User;
import com.traveldream.entity_managers.BookingManager;
import com.traveldream.entity_managers.CustomerManager;
import com.traveldream.entity_managers.PacketManager;

@ManagedBean(name="booking_manager_test")
@SessionScoped
public class BookingManagerTest implements TestingTravelDream {
	@EJB
	private BookingManager pm;
	@EJB
	private CustomerManager custm;
	@EJB
	private PacketManager packm;
	
	@ManagedProperty(value="#{test_bean}")
	private TestBean testBean;
	
	private String log;
	private StringBuilder logSb;

	@Override
	public void runTests() {
		logSb=new StringBuilder(300);
		logSb.append("******** TESTING DEL SESSION BEAN: BOOKING MANAGER *******");logSb.append(System.lineSeparator());
		logSb.append("***** INIZIO TESTING *****");	logSb.append(System.lineSeparator());
		logSb.append(System.lineSeparator());
		addTest();
		logSb.append(System.lineSeparator());
		findByParametersTest();
		logSb.append(System.lineSeparator());
		this.log=logSb.toString();
		System.out.print(this.log);
		testBean.setProd(false); testBean.setPack(false); testBean.setBook(true);	testBean.setInv(false);
	}

	@Override
	public void addTest() {
		logSb.append("*** ADD TEST BOOKING MANAGER ***");logSb.append(System.lineSeparator());
		List<Booking> initialState=pm.findAll();
		logSb.append("> INITIAL STATE: {");
		for( Booking e: initialState ) {
			BookingPK key=e.getId();
			logSb.append("   { "+key.getCustomerEmail()+","+key.getPacketId()+" }");
		}
		logSb.append("   }");
		logSb.append(System.lineSeparator());
		//
		if( custm.findAll().size()==0) {
			User u=new User();	u.setEmail("cust1"); u.setPassword("abc"); u.setName("alex"); u.setSurname("lipa");
			custm.create(u);
		}
		User u= custm.findAll().get(0);	
		Packet p=new Packet();	DefaultPacket dp=new DefaultPacket();	 dp.setPacket(p);	DefaultPacket dpn=packm.create(dp);
		Booking nuova=new Booking();
		BookingPK nuovaKey=new BookingPK();	nuovaKey.setCustomerEmail(u.getEmail()); nuovaKey.setPacketId(dpn.getPacketId());
		nuova.setUser(u); nuova.setPacket(p);
		nuova.setId(nuovaKey);
		Booking nn=pm.create(nuova);
		//
		logSb.append("> NEW BOOKING CREATED");	logSb.append(System.lineSeparator());
		logSb.append("> NEW BOOKING ADDED id = { "+nn.getId().getCustomerEmail()+","+nn.getId().getPacketId()+" }");logSb.append(System.lineSeparator());
		List<Booking> finalState=pm.findAll();
		logSb.append("> FINAL STATE: {");
		for( Booking e: finalState ) {
			BookingPK key=e.getId();
			logSb.append("   { "+key.getCustomerEmail()+","+key.getPacketId()+" }");
		}
		logSb.append("   }");
		logSb.append(System.lineSeparator());
		initialState.add(nuova);
		Comparator<Booking> comp=new Comparator<Booking>() {
			public int compare(Booking e1, Booking e2) { 
				if( ! e1.getUser().getEmail().equals(e2.getUser().getEmail()))
					return e1.getUser().getEmail().compareTo(e2.getUser().getEmail());
				else
					return e1.getPacket().getId()-e2.getPacket().getId();
			}
		};
		Collections.sort(initialState,comp);
		Collections.sort(finalState,comp);
		
		if( initialState.equals(finalState) )
			logSb.append(" *** TEST PERFORMED SUCCESSFULLY *** ");
		else
			logSb.append(" *** TEST FAILURE *** ");
		logSb.append(System.lineSeparator());
		logSb.append(" *** END ADD TEST ***");logSb.append(System.lineSeparator());
	}

	@Override
	public void deleteTest() {
		// non � prevista dal sistema la rimozione di prenotazioni
	}

	@Override
	public void addDeleteTest() {
		// non � prevista dal sistema la rimozione di prenotazioni
	}

	@Override
	public void updateTest() {
		// non � prevista dal sistema l'aggiornamento di una prenotazione
	}

	@Override
	public void findByParametersTest() {
		logSb.append("*** FIND TEST BOOKING MANAGER ***");logSb.append(System.lineSeparator());
		// view initial state
		List<Booking> initialState=pm.findAll();
		logSb.append("> INITIAL STATE: {");
		for( Booking e: initialState ) {
			BookingPK key=e.getId();
			logSb.append("   { "+key.getCustomerEmail()+","+key.getPacketId()+" }");
		}
		logSb.append("   }");
		logSb.append(System.lineSeparator());
		// create and add new booking
		if( custm.findAll().size()==0) {
			User u=new User();	u.setEmail("cust1"); u.setPassword("abc");
			custm.create(u);
		}
		User u= custm.findAll().get(0);	
		Packet p=new Packet();	DefaultPacket dp=new DefaultPacket();	 dp.setPacket(p);	DefaultPacket dpn=packm.create(dp);	
		Booking nuova=new Booking();
		BookingPK nuovaKey=new BookingPK();	nuovaKey.setCustomerEmail(u.getEmail()); nuovaKey.setPacketId(dpn.getPacketId());
		nuova.setUser(u); nuova.setPacket(p);
		nuova.setId(nuovaKey);
		GregorianCalendar d=new GregorianCalendar(2014,GregorianCalendar.JANUARY,30);
		nuova.setDate(d.getTime());		
		Booking nn=pm.create(nuova);
		logSb.append("> NEW BOOKING CREATED");	logSb.append(System.lineSeparator());
		logSb.append("> NEW BOOKING ADDED id = { "+nn.getId().getCustomerEmail()+","+nn.getId().getPacketId()+"}");logSb.append(System.lineSeparator());
		
		List<Booking> query=pm.findByCustomer(u);
		logSb.append("> QUERY EXECUTED find bookings for customer = "+u.getEmail());logSb.append(System.lineSeparator());
		
		//visualize results
		boolean found=false;
		logSb.append("> QUERY RESULTS: {");
		for( Booking x: query ) {
			if( x.getUser().getEmail().equals(u.getEmail()) ) {
				found=true;
				logSb.append("   { "+x.getId().getCustomerEmail()+","+x.getId().getPacketId()+" }");
			}
		}
		logSb.append("   }");
		logSb.append(System.lineSeparator());
		if( found )
			logSb.append(" *** TEST PERFORMED SUCCESSFULLY");
		else
			logSb.append(" *** TEST FAILURE *** ");
		logSb.append(System.lineSeparator());
		logSb.append(" *** END FIND TEST ***");	logSb.append(System.lineSeparator());
	}

	public TestBean getTestBean() {
		return testBean;
	}

	public void setTestBean(TestBean testBean) {
		this.testBean = testBean;
	}

	public String getLog() {
		return log;
	}

	public void setLog(String log) {
		this.log = log;
	}
}
